CCPP的三种函数传值方式及其区别

编程老大叔 2019-09-29 10:03:06

C/C++函数传参方式我想很多朋友应该都知道,但是不同传参方式的背后他们的区别是什么我想很多人并不那么清楚。本文就给大家揭露一下各传参方式的区别。

传参方式有这三种:值传递、引用传递、指针传递

大家可以去看三种传递方式的写法的区别,关于写法的区别就不在这里讲了。我只要将一下三种方式的运行效率和特征

值传递

我们在main函数里将func2和func3先注释掉,然后运行并查看汇编代码看看是什么结果,先看运行结果吧:

说实话,汇编其实我不是很懂,但是用来比较运行效率是够用了的。这里将汇编的几个指令给大家稍微讲一下吧。

MOV 传送字或字节. (mov ax 2把2放入寄存器)

PUSH 把字压入堆栈

CALL 过程调用

好,了解这几个就够了,我们可以看到值传递在调用方法的时候先进行了两次传值,然后再压栈然后call了一个系统函数然后又传了一次值然后才是调用了func1,总共6个步骤。

接下来我们看看运行完后我们

cout<<test<<endl;

看看test实参的变化,我们发现输出的还是:

origion

所以作为值传递,在运行函数后不管函数里面对实参进行了什么运算,是不会改变实参的值得

引用传递

接下来我们看一下引用传递,还是一样,先看汇编代码:

怎么样,是不是吓一跳,才两步,直接压栈然后就调用函数func2,这样运行速度该会比func1快多少呢。

下面看下实参test的变化,我们输出看一下:

changed

怎么样,是不是很神奇,居然将实参值给改变了,这是为什么呢?这是因为引用传递的时候是将参数的地址传递给了函数,这样在函数中的对实参所有操作都是直接在操作实参地址,所以他能将实参值改变。

指针传递

最后,我们看下指针传递,先看汇编代码:

步骤跟引用传递时一样的,然后我们看一下运行结果,输出一下test:

changed

我们发现实参也被改变了,这也是因为其实我们是将实参的地址传递给函数了。

实测效率差别

我们引入time.h来看运行时间。我们将每个方法的调用过程循环一百万次,看下运行时间差距

结果如下:

怎么样,这个差距还是蛮大的,这还是只有一个参数,要是多几个,并且参数尺寸大一些的话差距会更明显。最后把源代码给大家把,有兴趣的可以自己试一试

#include <stdio.h>

#include <string>

#include <iostream>

#include <time.h>

using namespace std;

string test = "origion" ;

string changed = "changed" ;

string getTime()

{

time_t tt =time(NULL);

tm* t =localtime(&tt);

t->tm_mon ;

string mon = to_string(t->tm_mon);

string day = to_string(t->tm_mday);

string hour = to_string(t->tm_hour);

string min = to_string(t->tm_min);

string sec = to_string(t->tm_sec);

string times = mon+"-"+day+":"+hour+":"+min+":"+sec ;

return times ;

}

void func1(string s)//值传递

{

s = changed ;

}

void func2(string& s)//引用传递

{

s = changed ;

}

void func3(string* s)//指针传递

{

*s = changed;

}

int main()

{

cout<<getTime()<<endl;

for (int i = 0; i < 1000000; i++)

{

func1(test);

}

cout<<getTime()<<endl;

for (int i = 0; i < 1000000; i++)

{

func2(test);

}

cout<<getTime()<<endl;

//func3(&test);

system("pause");

return 0 ;

}

本页共155段,3038个字符,4825 Byte(字节)